package com.lx.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.lx.common.ContextConst;
import com.lx.datasource.DynamicDataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import java.util.HashMap;

import javax.sql.DataSource;

/**
 * 多数据源配置
 *
 * @author 段誉
 * @create 2019-04-12 15:28
 */
@Configuration
@MapperScan(basePackages = MutiplyDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "dynamicDataSource")
public class MutiplyDataSourceConfig {

  public static final String PACKAGE = "com.lx.mapper";

  private static final String MAPPER_LOCATION = "classpath:mapper/*.xml";
  /**
   * 设置主数据源
   * @return
   */
  @Primary
  @Bean(name = "dynamicDataSource")
  public DataSource dynamicDataSource() {
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    //配置默认数据源
    dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());

    //配置多数据源
    HashMap<Object, Object> dataSourceMap = new HashMap<>();
    dataSourceMap.put(ContextConst.DataSourceType.PRIMARY.name(), primaryDataSource());
    dataSourceMap.put(ContextConst.DataSourceType.LOCAL.name(), localDataSource());
    dataSourceMap.put(ContextConst.DataSourceType.PROD.name(), prodDataSource());

    dynamicDataSource.setTargetDataSources(dataSourceMap);
    return dynamicDataSource;
  }
  @Bean(name = "dataSourcePrimary")
  @ConfigurationProperties(prefix = "spring.datasource.primary")
  public DataSource primaryDataSource() {
    return new DruidDataSource();
  }

  @Bean(name = "dataSourceLocal")
  @ConfigurationProperties(prefix = "spring.datasource.local")
  public DataSource localDataSource() {
    return new DruidDataSource();
  }

  @Bean(name = "dataSourceProd")
  @ConfigurationProperties(prefix = "spring.datasource.prod")
  public DataSource prodDataSource() {
    return new DruidDataSource();
  }

  /**
   * 配置@Transactional注解事务
   */
  @Bean
  public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dynamicDataSource());
  }

  @Bean(name = "dynamicDataSource")
  @Primary
  public SqlSessionFactory dynamicSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
          throws Exception {
    final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(dynamicDataSource);
    sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
            .getResources(MAPPER_LOCATION));
    return sessionFactory.getObject();
  }

}
